package org.totoro.analysisV2;

import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;

import java.util.ArrayList;
import java.util.List;

/**
 * @author daocr
 * @date 2020/9/24
 */
public class AnalysisClass extends ClassVisitor {


    private String className;
    private String methodName;
    private int api;
    private int level;

    private List<MethodStack> methodStacks = new ArrayList<>();
    private MethodStack parentMethodStack;

    private final int LIMIT_LEVEL = 2;

    public AnalysisClass(int api, int level, MethodStack parentMethodStack, String methodName) {
        super(api);
        this.api = api;
        this.level = level;
        this.parentMethodStack = parentMethodStack;
        this.methodName = methodName;
    }

    public AnalysisClass(int api, ClassVisitor classVisitor, int level, MethodStack parentMethodStack, String methodName) {
        super(api, classVisitor);
        this.api = api;
        this.level = level;
        this.parentMethodStack = parentMethodStack;
        this.methodName = methodName;
    }

    @Override
    public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {

        this.className = name;

        super.visit(version, access, name, signature, superName, interfaces);
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {

        if (methodName == null || methodName.equals(name)) {
            if (level >= LIMIT_LEVEL) {
                return super.visitMethod(access, name, descriptor, signature, exceptions);
            }

            MethodStack methodStack = new MethodStack(className, name, descriptor);

            if (parentMethodStack == null) {
                methodStacks.add(methodStack);
                return new AnalysisMethod(api, methodStack, 0);
            }

            parentMethodStack.getVisitMethod().add(methodStack);
            return new AnalysisMethod(api, methodStack, level + 1);
        }

        return super.visitMethod(access, name, descriptor, signature, exceptions);
    }
}
